package com.wang.utils

import org.apache.velocity.Template
import org.apache.velocity.VelocityContext
import org.apache.velocity.app.VelocityEngine
import org.apache.velocity.runtime.RuntimeConstants
import java.io.File
import java.io.FileWriter

object TemplateUtils {
    const val templateDir = "src\\main\\resource\\template"

    val ve = VelocityEngine().apply {
        this.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templateDir)
        this.init()
    }

    data class TemplateInfo(val name: String, val targetFileName: String, val template: Template)

    val TemplateMap = File("src\\main\\resource\\template").templateMap("")

    private fun File.templateMap(module: String): Map<String, TemplateInfo> = this.listFiles()!!.map { file ->
        if (!file.isDirectory) {
            val kv = file.name.replace(".vm", "").split("--")
            val k = if (module == "") kv[0] else "$module.${file.name}"
            mapOf(k to TemplateInfo(kv[0], kv[1], ve.getTemplate(file.name)))
        } else if (file.listFiles()?.size == 0) {
            emptyMap()
        } else {
            file.templateMap("$module.${file.name}")
        }
    }.reduce { acc, map -> acc.plus(map) }

    fun generate(name: String, param: Map<String, Any>, targetDir: File): File {
        targetDir.mkdirs()
        val info = TemplateMap[name]!!

        val filename = info.targetFileName.replace("\${name}", param["name"] as String)
        val targetFile = File(targetDir, filename)
        targetFile.createNewFile()

        val ctx = VelocityContext()
        param.forEach { (k, v) ->
            ctx.put(k, v)
        }

        val writer = FileWriter(targetFile)
        info.template.merge(ctx, writer)
        writer.flush()
        writer.close()
        return targetFile
    }
}
